<?php
// +----------------------------------------------------------------------
// | VueAdmin框架[基于ThinkPHP5开发]
// +----------------------------------------------------------------------
// | Copyright (c) 2016-2018 http://www.vueadmin.org
// +----------------------------------------------------------------------
// | VueAdmin承诺基础框架永久免费开源，您可用于学习和商用，但必须保留软件版权信息。
// +----------------------------------------------------------------------
// | Author: sept <917088650@qq.com>，开发者QQ群：63131383
// +----------------------------------------------------------------------

namespace app\system\model;


use app\lib\Auth\Auth;
use app\lib\exception\ApiException;
use app\lib\exception\ForbiddenException;
use app\lib\exception\TokenException;
use app\lib\returnCode\Code;
use app\lib\returnCode\Msg;
use app\system\controller\Token;

class AdminUser extends Base

{
    // 定义时间戳字段名
    protected $createTime = 'create_time';
    protected $updateTime = 'update_time';
    //TODO 等自定义异常类写完，开始规范Examples返回参数
    // 自动写入时间戳
    protected $autoWriteTimestamp = true;

    // 对密码进行加密
    public function setPasswordAttr($value)
    {
        return password_hash($value, PASSWORD_DEFAULT);
    }

    // 获取最后登陆ip
    public function setLastLoginIpAttr()
    {
        return request()->ip();
    }

    // 最后登录时间
    public function getLastLoginTimeAttr($value)
    {
        if (!$value) return '';
        return date('Y-m-d H:i', $value);
    }

    /**
     * 添加管理员
     * @param $data
     * @author sept <917088650@qq.com>
     * @return bool
     */
    public function add($data) {
       return self::save($data);
    }

    public function edit($id = '', $data = []) {

        //管理员权限认证
        if ($id == 1 || Auth::user()->id == $id) {// 禁止更改超管角色，当前登陆用户不可更改自己的角色
            unset($data['role_id']);
        }

        if ($data['password'] == 'VueAdmin') {
            unset($data['password']);
        }

        $res = $this->update($data,['id'=>$id]);

        return $res;
    }

    /**
     * 删除用户
     * @param int $id
     * @author sept <917088650@qq.com>
     * @return bool
     * @throws \Exception
     */
    public function del($id = 0)
    {
        if (is_array($id)) {
            $error = '';
            foreach ($id as $k => $v) {
                if ($v == Auth::id) {
                    throw new ApiException(Code::SYSTEM_ERROR_LOGIN_USER,sprintf(Msg::SYSTEM_ERROR_LOGIN_USER,$v));
                }

                if ($v == 1) {
                    throw new ApiException(Code::SYSTEM_ERROR_DELTE_ADMIN,sprintf(Msg::SYSTEM_ERROR_DELTE_ADMIN,$v));
                }

                if ($v <= 0) {
                    throw new ApiException(Code::SYSTEM_PARAMETER_ERROR,sprintf(Msg::SYSTEM_PARAMETER_ERROR,$v));
                }

                $map = [];
                $map['id'] = $v;
                // 删除用户
                self::where($map)->delete();
            }
        } else {
            $id = (int)$id;
            if ($id <= 0) {
                throw new ApiException(Code::SYSTEM_PARAMETER_ERROR,Msg::SYSTEM_PARAMETER_ERROR);
            }

            if ($id == Auth::id) {
                throw new ApiException(Code::SYSTEM_ERROR_LOGIN_USER,sprintf(Msg::SYSTEM_ERROR_LOGIN_USER,$v));
            }

            if ($id == 1) {
                throw new ApiException(Code::SYSTEM_ERROR_DELTE_ADMIN,sprintf(Msg::SYSTEM_ERROR_DELTE_ADMIN,$v));
            }
            $map = [];
            $map['id'] = $id;
            // 删除用户
            self::where($map)->delete();
        }

        return true;
    }

    /**
     * 用户登录
     * @param string $username
     * @param string $password
     * @param bool $remember
     * @author sept <917088650@qq.com>
     * @return bool|mixed
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     */
    public function login($username = '', $password = '', $remember = false)
    {
        $username = trim($username);
        $password = trim($password);
        $map = [];
        $map['status'] = 1;
        $map['username'] = $username;

        $user = self::where($map)->find();
        if (!$user) {
            throw new ApiException(Code::SYSTEM_USER_INFO_ERROR,Msg::SYSTEM_USER_INFO_ERROR);
        }

        // 密码校验
        if (!password_verify($password, $user->password)) {
            throw new ApiException(Code::USER_PASSWORD_ERROR,Msg::USER_PASSWORD_ERROR);
        }

        // 检查是否分配角色
        if ($user->role_id == 0) {
            throw new ApiException(Code::SYSTEM_ERROR_NO_CAT,sprintf(Msg::SYSTEM_ERROR_NO_CAT,'未分配角色!'));
        }

        // 角色信息
        $role = AdminRole::where('id', $user->role_id)->find();
        if (!$role || $role['status'] == 0) {
            throw new ApiException(Code::SYSTEM_ERROR_NO_CAT,sprintf(Msg::SYSTEM_ERROR_NO_CAT,'角色分组可能被禁用!'));
        }

        // 更新登录信息
        $user->last_login_time = time();
        $user->last_login_ip   = request()->ip;
        if ($user->save()) {
            // 缓存角色权限
            cache('role_auth_'.$user->role_id,  json_decode($role['auth'], true));

            //记住密码，Token有效期延长至一年
            if ($remember == 'true') {
                $extime = 31536000;
            } else {
                $extime = 7200;
            }

            $user['exp'] = request()->time() + $extime;

            //获取token
            $token = Token::access_token(['id'=>$user->id,'user'=>$user]);

            cache('Login:'.$user->id,$token);

            return [
                'access_token' => $token,
                'expires_in' => $extime,
                'request_in' => \request()->time(),
            ];
        }
        return false;
    }

    public function refresh_token() {
        //token还有一个小时过期,刷新token
        //获取token
        $newtoken = Token::access_token(['id'=>Auth::id,'user'=>Auth::user()]);

        cache('Login:'.request()->Auth->id,$newtoken);
        return [
            'access_token' => $newtoken,
            'expires_in' => 7200,
            'request_in' => \request()->time(),
        ];
    }

    /**
     * 退出登录
     * @author sept <917088650@qq.com>
     */
    public function logout()
    {
        //TODO 清除JWT
        cache('Login:'.Auth::id,'null');
    }

}